package io.renren.modules.clearing.service.impl;

import cn.com.taiji.common.manager.net.http.binclient.ApiRequestException;
import cn.com.taiji.sdk.comm.LwClientHelper;
import cn.com.taiji.sdk.model.comm.protocol.cdts.passTransaction.ETCAccountTradeDisputeRecord;
import cn.com.taiji.sdk.model.comm.protocol.cdts.passTransaction.ETCAccountTradeDownloadRequest;
import cn.com.taiji.sdk.model.comm.protocol.cdts.refundAndSettlement.ComplementDownloadRequest;
import cn.com.taiji.sdk.model.comm.protocol.cdts.refundAndSettlement.ComplementDownloadSplitTransaction;
import cn.com.taiji.sdk.model.comm.protocol.cdts.refundAndSettlement.ComplementDownloadTransaction;
import io.renren.common.utils.*;
import io.renren.modules.basedata.entity.XJException;
import io.renren.modules.clearing.dao.*;
import io.renren.modules.clearing.entity.*;
import io.renren.modules.clearing.service.ComplementDownloadService;
import io.renren.modules.clearing.service.ETCAccountTradeDownService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ComplementDownloadServiceImpl implements ComplementDownloadService {
    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    ComplementDownloadDao complementDownloadDao;
    @Autowired
    DataExchangeListDao dataExchangeListDao;
    @Autowired
    DataExchangeLogDao dataExchangeLogDao;
    @Autowired
    DownVersionDicDao downVersionDicDao;
    @Autowired
    DownErrorVersionDao downErrorVersionDao;
    @Autowired
    ConfigParaDicDao configParaDicDao;
    @Override
    public boolean complementDownload(String version, String sender, int type) throws Exception {

        boolean flag=false;
        ComplementDownloadRequest request = new ComplementDownloadRequest();
        request.setVersion(version);
        request.setReqSender(sender);
        String FilePath = "";
        try {
            File file =LwClientHelper.downLoad(request, sender==Config.issuerId?Constants.DOWNLOAD_PATH_COMPLEMENT:Constants.DOWNLOAD_PATH_COMPLEMENTSERVICE);
            //File file =new File("F:\\download\\ComplementTransaction\\20181209.zip");
            System.out.println("补交交易文件下载成功，下载文件为："+file.getAbsolutePath());
            //解压文件
            String filedir=file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("."));
            FilePath = "--文件:"+file.getAbsolutePath();
            ZipUncompress.unZip(file.getAbsolutePath(),filedir);
            //获取解压目录下的所有文件
            List<File> filelist = FileTool.getFileList(filedir);
            log.info("解压补交交易文件共"+filelist.size()+"个json文件");
            if(filelist.size()==0){
                log.info("补交交易文件为空包文件，退出任务");
                return true;
            }
            //循环解析所有文件入库
            String fileName=null;
            Date nowTime= new Date();
            for (File f :filelist) {
                fileName = f.getName();
                log.info("开始解析"+fileName+"文件");
                String filejsonstr=	FileTool.getjsonStr(filedir+"\\"+fileName);
                FilePath = "--文件:"+file.getAbsolutePath() +"\\"+fileName;
                log.info(fileName+"文件内容："+filejsonstr);

                //将json串转对象
                ComplementDownload etc= (ComplementDownload) FileTool.parseJsonToObj(filejsonstr, ComplementDownload.class);
                if(etc!=null){
                    //校验数据
                    if(etc.getMessageList()==null){
                        log.info("补交文件包："+etc.getRestitutionId()+"服务方："+etc.getReceiverId()+"数据格式异常");
                        throw new XJException(sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                                version, "补交交易下载请求失败交易包："+etc.getRestitutionId()+"服务方："+etc.getReceiverId()+"数据格式异常,无明细数据"+FilePath, 4);
                    }

                    //校验文件是否已经接收过   REFUNDID退费文件ID
                    Long id=etc.getRestitutionId();
                    int num = complementDownloadDao.getRestitutionIDExist(id);
                    //int num=(Integer) sqlMapClient.queryForObject("refundComplement_ORACLE.getRestitutionIDExist", id);
                    if(num>0){
                        log.info("补交文件包："+etc.getRestitutionId()+"已存在");
                        throw new XJException(sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                                version, "补交交易下载请求失败交易包："+etc.getRestitutionId()+"已存在"+FilePath, 4);
                    }

                    //交易文件中的总计和明细是否一致条数与汇总是否一致
                    int massageCount = 0;
                    Long messageAmount = 0L;
                    for(int i=0;i<etc.getMessageList().size();i++){
                        massageCount = massageCount+etc.getMessageList().get(i).getCount();
                        messageAmount = messageAmount+etc.getMessageList().get(i).getAmount();
                    }
                    if(etc.getCount()!=massageCount){
                        log.info("补交总流量："+etc.getCount()+"与补交流水明细条数："+massageCount+"不一致");
                        throw new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                                version, "补交交易下载请求响应失败交易包："+etc.getRestitutionId()+"总流量："+etc.getCount()+"与流水明细条数："+massageCount+"不一致"+FilePath, 4);
                    }
                    //交易文件中的总计和明细是否一致总金额与汇总是否一致
                    if(!messageAmount.equals(etc.getAmount())){
                        log.info("补交总金额："+etc.getAmount()+"与补交流水合计金额："+messageAmount+"不一致");
                        throw new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                                version, "补交交易下载请求响应失败交易包："+etc.getRestitutionId()+"总金额："+etc.getAmount()+"与流水合计金额："+messageAmount+"不一致"+FilePath, 4);
                    }
                    //保存补交数据
                    int tradeType = etc.getTradeType();
                    for (int i = 0; i < etc.getMessageList().size(); i++) {
                        ComplementDownloadMessage message = etc.getMessageList().get(i);
                        for(int j=0;j<message.getTransaction().size();j++){
                            ComplementDownloadTransaction transaction = message.getTransaction().get(j);
                            tbl_RestitutionTransaction restitutionTransaction =fullConplementWaste(etc, message, transaction, version, sender);
                            restitutionTransaction.setTRADETYPE(tradeType);
                            complementDownloadDao.addRestTrans(restitutionTransaction);
                            //sqlMapClient.insert("refundComplement_ORACLE.addRestTrans",restitutionTransaction);
                        }

                        //保存数据

                        //Tbl_DataExchangeList插入
                        DataExchangeList dataExchangeList= new DataExchangeList();
                        dataExchangeList.setMessageID(message.getMessageId().toString());
                        dataExchangeList.setSenderID(etc.getReceiverId());  //不确定
                        dataExchangeList.setReceiverID(Config.issuerId);
                        dataExchangeList.setProcessTime(nowTime);
                        dataExchangeList.setMessageClass(2);  //1请求;2请求应答;3建议;4建议应答;5通知;6:通知应答
                        dataExchangeList.setMessageType(7); //7:交易
                        dataExchangeList.setContentType(3); //3异常交易补交
                        dataExchangeList.setResult(1); //1消息正常接收;2消息头错误;3验证未通过;4消息格式正确但内容错误;5消息重复;6消息版本错误
                        dataExchangeList.setRecCount(etc.getCount());
                        dataExchangeList.setRecAmount(etc.getAmount());
                        dataExchangeList.setVersion(Integer.parseInt(version));
                        dataExchangeList.setReplyFlag(1); //1 收到确认消息;-1  默认值 不进行处理;0  等待确认报文;-2 接收到省外流水 等待记账
                        dataExchangeList.setReplyTime(nowTime);
                        dataExchangeList.setFileName(file.getName());
                        dataExchangeList.setResultDesc("原始补交交易下载成功");
                        dataExchangeList.setSpare1(message.getMessageId().toString());
                        dataExchangeList.setSpare3("原始补交交易下载");
                        dataExchangeListDao.addDataExchangeList(dataExchangeList);
                        //sqlMapClient.insert("Base_ORACLE.addDataExchangeList",dataExchangeList);
                        //插入日志
                        DataExchangeLog dataLog = addLog(etc, message,1, "原始补交交易下载成功", sender);
                        dataExchangeLogDao.addDataExchangeLog(dataLog);
                        //sqlMapClient.insert("Base_ORACLE.addDataExchangeLog",dataLog);
                    }
                }else{
                    log.info("解析补交交易"+fileName+"文件转换对象失败");
                    //添加版本异常表
                    throw new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                            version, "补交交易下载请求响应失败解析"+fileName+"文件转换对象失败"+FilePath, 4);
                }
                //删除文件
                f.delete();
            }
            if(type==1){
                addDownErrorVersion(version,sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                        "补交交易下载请求响成功文件："+file.getAbsolutePath(), 0);
                //修改下载版本号
                version=TypeTransUtil.getNextVersion(version, Constants.DOWNLOAD_FILE_1D);
                Map map2 = new HashMap<>();
                map2.put("version", version);
                map2.put("MsgType", sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD);
                downVersionDicDao.editVersion(map2);
                //sqlMapClient.update("Base_ORACLE.editVersion",map2);
            }
            //删除文件夹
            File F = new  File(filedir);
            F.delete();
            flag=true;

        } catch (IOException e) {
            // TODO: handle exception
            log.info("补交交易下载请求响应失败,版本号："+version+":"+e.getMessage());
            throw new Exception(new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                    version, "补交交易下载请求响应失败IO异常,版本号："+version+":"+e.getMessage()+FilePath, 1));
        } catch (ApiRequestException apie) {
            //TODO 系统自定义异常处理，各省补全
            apie.printStackTrace();
            if(apie.getErrCode()==Constants.EMPTYDATACODE){
                log.info("补交交易下载请求无数据711,版本号："+version+":正常退出");
                if(type==1){
                    addDownErrorVersion(version, sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                            "补交交易下载请求响成功无数据"+FilePath, 0);
                    //修改下载版本号
                    version=TypeTransUtil.getNextVersion(version, Constants.DOWNLOAD_FILE_1D);
                    Map map2 = new HashMap<>();
                    map2.put("version", version);
                    map2.put("MsgType", sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD);
                    downVersionDicDao.editVersion(map2);
                    //sqlMapClient.update("Base_ORACLE.editVersion",map2);
                }
                flag=true;
            }else{
                log.error("补交交易下载请求响应失败,版本号："+version+"错误码："+apie.getErrCode()+" 错误信息："+apie.getMessage());
                throw new Exception(new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                        version, "补交交易下载请求响应失败错误码："+apie.getErrCode()+" 错误信息："+apie.getMessage()+FilePath, apie.getErrCode()));
            }
        }catch (XJException e) {
            throw new Exception(e);
        }catch (SQLException e) {
            String msg=TypeTransUtil.getErrorMessage(e.getMessage()) ;
            throw new Exception(new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                    version, "补交交易下载请求响应失败，SQL异常:"+msg+FilePath, 7));
        }catch (Exception e) {
            String msg=TypeTransUtil.getErrorMessage(e.getMessage()) ;
            throw new Exception(new XJException( sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD,
                    version, "补交交易下载请求响应失败，其他异常:"+msg+FilePath, 3));
        }
        return flag;

    }

    @Override
    public String[] getComplementDownVersion(String sender) throws Exception {

        String msg="";
        String version=null;
        String[] versions=null;
        log.info("开始检查 补交交易下载 控制参数");
        //检查控制参数是否下载 tbl_configparadic
        int control = configParaDicDao.checkContolParam(Constants.CONTROL_TCSRESDDOWN_PARAM);
        //int control=(Integer) sqlMapClient.queryForObject("Base_ORACLE.checkContolParam",Constants.CONTROL_TCSRESDDOWN_PARAM);
        //int control = 1;
        if(control==1){
            //获取要需下载的版本号
            version = downVersionDicDao.getVersion(sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD);
            //version=(String) sqlMapClient.queryForObject("Base_ORACLE.getVersion",sender==Config.issuerId?Constants.DOWNLOAD_TYPE_COMPLEMENTDOWNLOAD:Constants.DOWNLOAD_TYPE_COMPLEMENTSERVICEDOWNLOAD);
            //version = "20181211";
            if(version!=null ){
                //判断有多少版本号要处理
                versions=TypeTransUtil.checkVersion(version, Constants.DOWNLOAD_FILE_1D); //一天一个版本

            }else{
                msg="版本字典表 补交交易下载 参数配置";
                log.info(msg);
            }
        }else{
            msg="补交交易下载 接口暂停，任务退出";
            log.info(msg);
        }
        return versions;

    }


    /**
     * 添加异常版本信息
     * @param version
     * @param reason
     * @param flag 0异常错误 ；1校验错误
     * @throws Exception
     */
    public void addDownErrorVersion(String version,int type,String reason,int flag)throws Exception{
        //添加版本异常表
        DownErrorVersion dv=TypeTransUtil.addDownErrorVersion(version,type, reason);
        dv.setFlag(flag);
        int count = downErrorVersionDao.selectDownErrorVersion(dv);
        //int count =(Integer) sqlMapClient.queryForObject("Base_ORACLE.selectDownErrorVersion",dv);
        if(count>0){
            downErrorVersionDao.editDownErrorVersion(dv);
            //sqlMapClient.update("Base_ORACLE.editDownErrorVersion",dv);
        }else{
            downErrorVersionDao.addDownErrorVersion(dv);
            //sqlMapClient.insert("Base_ORACLE.addDownErrorVersion",dv);
        }
    }

    /**
     * 转换成 补交 流水
     * @param
     * @param transaction
     * @param message
     * @return
     * @throws Exception
     */
    public tbl_RestitutionTransaction fullConplementWaste(ComplementDownload down, ComplementDownloadMessage message, ComplementDownloadTransaction transaction, String version, String sender)throws Exception{
        tbl_RestitutionTransaction rest = new tbl_RestitutionTransaction();
        //PAYERID	付款方
        rest.setPAYERID(down.getPayerId());
        //PAYERTYPE	付款方类型
        rest.setPAYERTYPE(down.getPayerType());
        //RECEIVERID	收款方
        rest.setRECEIVERID(down.getReceiverId());
        //RECEIVERTYPE	收款方类型
        rest.setRECEIVERTYPE(down.getReceiverType());
        //RESTITUTIONID	补交文件ID
        rest.setRESTITUTIONID(down.getRestitutionId());
        //PROCESSTIME	处理时间
        rest.setPROCESSTIME(new Date());
        //MESSAGEID	交易包号
        rest.setMESSAGEID(message.getMessageId());
        //TRANSACTIONID	交易编号
        rest.setTRANSACTIONID(transaction.getTransactionId());
        //ID	补交流水编号
        rest.setID(transaction.getId());
        //FEE	补交金额
        rest.setFEE(transaction.getFee());
        //RESTITUTIONTYPE	补交业务类型
        rest.setRESTITUTIONTYPE(transaction.getRestitutionType());
        //ORDERID	工单号
        rest.setORDERID(transaction.getOrderId());
        //SPLITTRANSACTIONCOUNT	拆分明细数量
        rest.setSPLITTRANSACTIONCOUNT(transaction.getSplitTransaction().size());
        //SPLITTRANSACTION	拆分明细
        StringBuffer SPLITTRANSACTION = new StringBuffer();
        for(int i=0;i<transaction.getSplitTransaction().size();i++){
            ComplementDownloadSplitTransaction detail = transaction.getSplitTransaction().get(i);
            SPLITTRANSACTION.append(detail.getId()+"|"+detail.getSectionId()+"|"+detail.getFee()+";");
        }
        rest.setSPLITTRANSACTION(SPLITTRANSACTION.toString().substring(0, SPLITTRANSACTION.length()-1)); //补交拆分数据	拆分结果编号|收费路段编号收费路段拆分金额

        //VERSION	补交文件版本号
        rest.setVERSION(version);
        //CLEARDATE	结算日期
        //refund.set
        //TYPE	数据类型
        if(sender.equals(Config.issuerId)){ //数据类型  1-发行接口下载2-服务方接口下载
            rest.setTYPE(1);
        }else{
            rest.setTYPE(2);
        }
        return rest;
    }

    /**
     * 封装日志
     */
    public DataExchangeLog addLog(ComplementDownload down, ComplementDownloadMessage message,int result,String ResultDesc, String sender ) throws Exception{
        DataExchangeLog dataLog = new DataExchangeLog();
        dataLog.setWasteSN(new GUID().toString());
        dataLog.setMessageID(message.getMessageId().toString());
        dataLog.setTollProvinceId(down.getReceiverId());  //待确定
        dataLog.setIssuerID(Config.issuerId);
        dataLog.setSerProvinceID(down.getPayerId());  //待确定
        dataLog.setProcessTime(new Date());
        dataLog.setMessageClass(22); // 21:退费文件下载22:补交文件下载
        dataLog.setMessageType(7);  //6退费 7补交
        dataLog.setResult(result);
        dataLog.setRecCount(message.getCount());
        dataLog.setDisputedCount(0);
        dataLog.setRecAmount(message.getAmount());
        dataLog.setResultDesc(ResultDesc);
        return dataLog;
    }
    /**
     * 封装日志
     */
    public DataExchangeLog addErrorLog(int result,String ResultDesc ) throws Exception{
        DataExchangeLog dataLog = new DataExchangeLog();
        dataLog.setWasteSN(new GUID().toString());
        dataLog.setMessageID("0");
        dataLog.setTollProvinceId("0");
        dataLog.setIssuerID(Config.issuerId);
        dataLog.setSerProvinceID("0");
        dataLog.setProcessTime(new Date());
        dataLog.setMessageClass(22);  //21:退费文件下载22:补交文件下载
        dataLog.setMessageType(7);  //6退费7补交
        dataLog.setResult(result);
        dataLog.setRecCount(0);
        dataLog.setDisputedCount(0);
        dataLog.setRecAmount(0);
        dataLog.setResultDesc(ResultDesc);
        return dataLog;
    }
}

